package com.swallow.auth.infrastructure.acl.oauth2.serializer;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.MissingNode;
import com.swallow.auth.infrastructure.mysql.po.AccountPO;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.time.LocalDateTime;

/**
 * @author: yangjie.deng@resico.cn
 * @since: 2024-05-14 14:30:16
 * @version: v1.0.0
 * @describe:  自定义 JdbcOAuth2AuthorizationService对 refresh_token grant_type用来反序列化.
 */
public class AccountDeserializer extends JsonDeserializer<AccountPO> {

    @Override
    public AccountPO deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JacksonException {
        ObjectMapper mapper = (ObjectMapper) parser.getCodec();
        JsonNode jsonNode = mapper.readTree(parser);

        var id =                 readJsonNode(jsonNode, "id").asLong();
        var accountNo =          readJsonNode(jsonNode, "accountNo").asText();
        var mobile  =            readJsonNode(jsonNode, "mobile").asText();
        var username =           readJsonNode(jsonNode, "accountName").asText();
        var password =           readJsonNode(jsonNode, "accountPassword").asText();
        var registerTime =       readJsonNode(jsonNode, "registerTime").asText();
        var accountStatus =      readJsonNode(jsonNode, "accountStatus").asInt();
        var loginErrorCount =    readJsonNode(jsonNode, "loginErrorCount").asInt();
        var loginTime =          readJsonNode(jsonNode, "loginTime").asText();
        var accountLockStatus =  readJsonNode(jsonNode, "accountLockStatus").asInt();
        var accountUnlockTime =  readJsonNode(jsonNode, "accountUnlockTime").asText();
        var tenantNo =           readJsonNode(jsonNode, "tenantNo").asText();
        var tenantName =         readJsonNode(jsonNode, "tenantName").asText();
        var staffName =          readJsonNode(jsonNode, "staffName").asText();
        var createTime =         readJsonNode(jsonNode, "createTime").asText();
        var updateTime =         readJsonNode(jsonNode, "updateTime").asText();
        var deleteFlag =         readJsonNode(jsonNode, "deleteFlag").asLong();

        AccountPO account = new AccountPO();
        account.setId(id);
        account.setAccountNo(accountNo);
        account.setMobile(mobile);
        account.setAccountName(username);
        account.setAccountPassword(password);
        account.setRegisterTime(dateParse(registerTime));
        account.setAccountStatus(accountStatus);
        account.setLoginErrorCount(loginErrorCount);
        account.setLoginTime(dateParse(loginTime));
        account.setAccountLockStatus(accountLockStatus);
        account.setAccountUnlockTime(dateParse(accountUnlockTime));
        account.setTenantNo(tenantNo);
        account.setTenantName(tenantName);
        account.setStaffName(staffName);
        account.setCreateTime(dateParse(createTime));
        account.setUpdateTime(dateParse(updateTime));
        account.setDeleteFlag(deleteFlag);

        return account;
    }


    private LocalDateTime dateParse(String time) {
        return StringUtils.isBlank(time) || StringUtils.equals("null", time) ? null : LocalDateTime.parse(time);
    }

    private JsonNode readJsonNode(JsonNode jsonNode, String field) {
        return jsonNode.has(field) ? jsonNode.get(field) : MissingNode.getInstance();
    }
}
